package com.zjm.creational.prototype.deepclone;

import javax.swing.*;
import java.io.*;

public class DeepPrototype implements Serializable, Cloneable {

    private String name;
    private DeepCloneableTarget deepCloneableTarget; //引用类型数据

    public DeepPrototype() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public DeepCloneableTarget getDeepCloneableTarget() {
        return deepCloneableTarget;
    }

    public void setDeepCloneableTarget(DeepCloneableTarget deepCloneableTarget) {
        this.deepCloneableTarget = deepCloneableTarget;
    }

    /**
     * 深拷贝-方式一 使用clone方法
     *
     * @return
     */
    @Override
    protected Object clone() {
        DeepPrototype deepPrototype = null;
        try {
            // 这里完成对基本数据类型和String类型数据克隆
            deepPrototype = (DeepPrototype) super.clone();
            // 对引用数据类型克隆
            deepPrototype.deepCloneableTarget = (DeepCloneableTarget) deepCloneableTarget.clone();
        } catch (CloneNotSupportedException e) {

        }
        return deepPrototype;
    }

    /**
     * 深拷贝-方式二 通过对象的序列化实现
     *
     * @return
     */
    public Object deepClone() {

        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;

        try {
            // 序列化
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this); //转为流

            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            DeepPrototype deepPrototype = (DeepPrototype) ois.readObject();
            return deepPrototype;
        } catch (Exception e) {
            return null;
        } finally {

            try {
                if (bos != null) {
                    bos.close();
                }
                if (oos != null) {
                    oos.close();
                }
                if (bis != null) {
                    bis.close();
                }
                if (ois != null) {
                    ois.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
